package com.sls.api.game.servlet.downstream;

import java.io.IOException;
import java.rmi.ServerException;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.sls.api.game.constant.Constant;
import com.sls.api.game.constant.ExCodeDes;
import com.sls.api.game.pojo.GoodsTransaction;
import com.sls.api.game.pojo.GoodsTransactionInfo;
import com.sls.api.game.servlet.SuperServlet;
import com.sls.api.util.DataDeal;
import com.sls.api.util.IpUtil;
import com.sls.api.util.OrganizeRespXmlData;
import com.sls.api.util.ResponseDataXmlFormat;
import com.sls.api.util.SecretKeyUtil;
import com.sls.api.util.UtilMD5Encryption;
import com.sls.core.common.CommonUtil;
import com.sls.core.socket.Head;
import com.sls.core.socket.SocketDTO;

/**
 * 直充交易接口
 * 
 * @author Administrator
 * 
 */
public class GoodsTransactionServlet extends SuperServlet {

	private static final long serialVersionUID = 684753455328077413L;
	private static Logger log = Logger.getLogger(GoodsTransactionServlet.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServerException, IOException, UnavailableException {
		req.setAttribute("org.eclipse.jetty.server.Request.queryEncoding",
				"UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		resp.setStatus(HttpServletResponse.SC_OK);
		log.info("下游请求参数：" + req.getQueryString());
		try {
			// 合作方用户账号
			String userNo = req.getParameter("userNo");
			if (StringUtils.isNotEmpty(userNo)) {
				userNo = userNo.trim();
			}

			// 商品编号
			String goodsId = req.getParameter("goodsId");
			if (StringUtils.isNotEmpty(goodsId)) {
				goodsId = goodsId.trim();
			}
			// 合作方订单编号
			String ptOrderNo = req.getParameter("ptOrderNo");
			if (StringUtils.isNotEmpty(ptOrderNo)) {
				ptOrderNo = ptOrderNo.trim();
			}
			// 合作方买家付款时间
			String ptPayTime = req.getParameter("ptPayTime");
			if (StringUtils.isNotEmpty(ptPayTime)) {
				ptPayTime = ptPayTime.trim();
			}
			// 购买数量
			String buyNum = req.getParameter("buyNum");
			if (StringUtils.isNotEmpty(buyNum)) {
				buyNum = buyNum.trim();
			}
			// 该商品供货单价
			String unitPrice = req.getParameter("unitPrice");
			if (StringUtils.isNotEmpty(unitPrice)) {
				unitPrice = unitPrice.trim();
			}
			// 总价
			String totalPrice = req.getParameter("totalPrice");
			if (StringUtils.isNotEmpty(totalPrice)) {
				totalPrice = totalPrice.trim();
			}
			// 游戏玩家账号
			String gameAccount = req.getParameter("gameAccount");
			if (StringUtils.isNotEmpty(gameAccount)) {
				gameAccount = gameAccount.trim();
			}
			// 游戏所在区域
			String gameArea = req.getParameter("gameArea");
			if (StringUtils.isNotEmpty(gameArea)) {
				gameArea = gameArea.trim();
			}
			// 游戏所在服务器组
			String gameServer = req.getParameter("gameServer");
			if (StringUtils.isNotEmpty(gameServer)) {
				gameServer = gameServer.trim();
			}
			String accountTypeName = req.getParameter("accountTypeName");
			if (StringUtils.isNotEmpty(accountTypeName)) {
				accountTypeName = accountTypeName.trim();
			}
			String chargeTypeName = req.getParameter("chargeTypeName");
			if (StringUtils.isNotEmpty(chargeTypeName)) {
				chargeTypeName = chargeTypeName.trim();
			}
			String notifyUrl = req.getParameter("notifyUrl");
			if (StringUtils.isNotEmpty(notifyUrl)) {
				notifyUrl = notifyUrl.trim();
			}

			// 最终购买用户IP
			String merchantIP = req.getParameter("merchantIP");
			if (StringUtils.isNotEmpty(merchantIP)) {
				merchantIP = merchantIP.trim();
			}

			//省域编码
			String provinceCode = req.getParameter("provinceCode");
			if (StringUtils.isNotEmpty(provinceCode)) {
				provinceCode = provinceCode.trim();
			}
			
			// 签名字符串
			String sign = req.getParameter("sign");
			if (StringUtils.isNotEmpty(sign)) {
				sign = sign.trim();
			}

			boolean flag = this.validateData(userNo, goodsId, ptOrderNo,
					ptPayTime, buyNum, unitPrice, totalPrice, gameAccount,
					gameArea, gameServer, accountTypeName, chargeTypeName,
					notifyUrl, sign, resp, req,merchantIP,provinceCode);

			if (flag) {// 校验成功
				Gson gson = CommonUtil.gson();
				SocketDTO dto = orgGsonSocket(userNo, goodsId, ptOrderNo,
						ptPayTime, buyNum, unitPrice, totalPrice, gameAccount,
						gameArea, gameServer, notifyUrl, req, accountTypeName,
						chargeTypeName, merchantIP,provinceCode);
				Head head = dto.getHead();
				String resCode = head.getResponseCode();
				String resMsg = head.getResponseMessage();
				String body = dto.getBody();
				GoodsTransactionInfo goodsTransaction = null;
				if (StringUtils.isNotEmpty(body)) {
					goodsTransaction = gson.fromJson(body,
							GoodsTransactionInfo.class);
					// try {
					// String date = CreateXMLByDom4j.createDateString();
					// String realPath = PropertiesUtil
					// .getValue("bill.project.path");
					// String folderName = PropertiesUtil
					// .getValue("bill.folder.name");
					// String filePath = realPath + File.separator + folderName
					// + File.separator + date + File.separator + date
					// + userNo + ".xml";
					// CreateXMLByDom4j.createCheckAccountFile(filePath, userNo,
					// ptOrderNo, gameAccount, goodsId, unitPrice, buyNum,
					// goodsTransaction.getStatus(), totalPrice, date);
					// } catch (Exception e) {
					// log.error("生成对账文件异常！", e);
					// }
				}
				if (goodsTransaction == null) {
					ResponseDataXmlFormat.returnFailMsg(
							ExCodeDes.UNKNOW_ERROR.getCode(),
							ExCodeDes.UNKNOW_ERROR.getDescription(), resp);
					return;
				}

				String xmlData = OrganizeRespXmlData
						.assembleXmlForGoodsTransaction(resCode, resMsg,
								goodsTransaction);
				log.info("请求ID：" + head.getRequestId() + "（直充交易）同步返回给下游的消息："
						+ xmlData);
				resp.getWriter().write(xmlData);
				resp.getWriter().flush();
				resp.getWriter().close();
			}
		} catch (Exception e) {
			log.error("系统异常！", e);
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.UNKNOW_ERROR.getCode(),
					ExCodeDes.UNKNOW_ERROR.getDescription(), resp);
		}

	}

	/**
	 * 组织gson报文
	 * 
	 * @param userId
	 * @param userPwd
	 * @param goodsId
	 * @param ptOrderNo
	 * @param ptPayTime
	 * @param buyNum
	 * @param unitPrice
	 * @param totalPrice
	 * @param gameAccount
	 * @param gameArea
	 * @param gameServer
	 * @param req
	 * @return
	 */
	private SocketDTO orgGsonSocket(String userNo, String goodsId,
			String ptOrderNo, String ptPayTime, String buyNum,
			String unitPrice, String totalPrice, String gameAccount,
			String gameArea, String gameServer, String notifyUrl,
			HttpServletRequest req, String accountTypeName,
			String chargeTypeName, String clientIp,String provinceCode) {
		GoodsTransaction goods = new GoodsTransaction();
		goods.setUserNo(userNo);
		goods.setGoodsId(goodsId);
		goods.setPtOrderNo(ptOrderNo);
		goods.setPtPayTime(ptPayTime);
		goods.setMerchantIP(clientIp);
		goods.setBuyNum(buyNum);
		goods.setUnitPrice(unitPrice);
		goods.setTotalPrice(totalPrice);
		goods.setGameAccount(gameAccount);
		goods.setGameArea(gameArea);
		goods.setGameServer(gameServer);
		goods.setNotifyUrl(notifyUrl);
		goods.setAccountTypeName(accountTypeName);
		goods.setChargeTypeName(chargeTypeName);
		goods.setClientIp(clientIp);
		goods.setProvinceCode(provinceCode);

		Head head = new Head();
		head.setRequestId(UUID.randomUUID().toString());
		head.setServiceCode(Constant.TRADING);
		head.setIp(IpUtil.getIpAddr(req));
		head.setUserId(userNo);
		return super.send(head, goods);
	}

	/**
	 * 数据校验
	 * 
	 * @param userNo
	 * @param userPwd
	 * @param goodsId
	 * @param ptOrderNo
	 * @param ptPayTime
	 * @param buyNum
	 * @param unitPrice
	 * @param totalPrice
	 * @param gameAccount
	 * @param gameArea
	 * @param gameServer
	 * @param accountTypeName
	 * @param chargeTypeName
	 * @param notifyUrl
	 * @param sign
	 * @param resp
	 * @param req
	 * @return
	 * @throws IOException
	 */
	private boolean validateData(String userNo, String goodsId,
			String ptOrderNo, String ptPayTime, String buyNum,
			String unitPrice, String totalPrice, String gameAccount,
			String gameArea, String gameServer, String accountTypeName,
			String chargeTypeName, String notifyUrl, String sign,
			HttpServletResponse resp, HttpServletRequest req,String merchantIP,
			String provinceCode)throws IOException {
		boolean result = false;
		if (StringUtils.isEmpty(userNo)) {
			log.info("交易时,合作方用户账号为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription() + "[userNo]!",
					resp);
			return false;
		} else if (StringUtils.isEmpty(goodsId)) {
			log.info("交易时,合作方商品编号为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription() + "[goodsId]!",
					resp);
			return false;
		} else if (StringUtils.isEmpty(ptOrderNo)) {
			log.info("交易时,合作方订单编号为空!!!");
			ResponseDataXmlFormat
					.returnFailMsg(ExCodeDes.PARAMETER_EMPTY.getCode(),
							ExCodeDes.PARAMETER_EMPTY.getDescription()
									+ "[ptOrderNo]!", resp);
			return false;
		} else if (StringUtils.isEmpty(ptPayTime)) {
			log.info("交易时,合作方买家付款时间为空!!!");
			ResponseDataXmlFormat
					.returnFailMsg(ExCodeDes.PARAMETER_EMPTY.getCode(),
							ExCodeDes.PARAMETER_EMPTY.getDescription()
									+ "[ptPayTime]!", resp);
			return false;
		} else if (StringUtils.isEmpty(buyNum)) {
			log.info("交易时,合作方用户购买数量为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription() + "[buyNum]!",
					resp);
			return false;
		} else if (StringUtils.isEmpty(unitPrice)) {
			log.info("交易时,该商品供货单价为空!!!");
			ResponseDataXmlFormat
					.returnFailMsg(ExCodeDes.PARAMETER_EMPTY.getCode(),
							ExCodeDes.PARAMETER_EMPTY.getDescription()
									+ "[unitPrice]!", resp);
			return false;
		} else if (StringUtils.isEmpty(totalPrice)) {
			log.info("交易时,总价为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription()
							+ "[totalPrice]!", resp);
			return false;
		} else if (StringUtils.isEmpty(gameAccount)) {
			log.info("交易时,游戏玩家账号为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription()
							+ "[gameAccount]!", resp);
			return false;
		} else if (StringUtils.isEmpty(notifyUrl)) {
			log.info("交易时,回调地址为空!!!");
			ResponseDataXmlFormat
					.returnFailMsg(ExCodeDes.PARAMETER_EMPTY.getCode(),
							ExCodeDes.PARAMETER_EMPTY.getDescription()
									+ "[notifyUrl]!", resp);
			return false;
		} else if (StringUtils.isEmpty(sign)) {
			log.info("交易时,签名字符串为空!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PARAMETER_EMPTY.getCode(),
					ExCodeDes.PARAMETER_EMPTY.getDescription() + "[sign]!",
					resp);
			return false;
		} else {
			StringBuilder builder = new StringBuilder();
			builder.append(userNo);
			builder.append(goodsId);
			builder.append(ptOrderNo);
			builder.append(ptPayTime);
			builder.append(buyNum);
			builder.append(unitPrice);
			builder.append(totalPrice);
			builder.append(gameAccount);
			if (StringUtils.isNotEmpty(gameArea)) {
				builder.append(gameArea);
			}
			if (StringUtils.isNotEmpty(gameServer)) {
				builder.append(gameServer);
			}
			if (StringUtils.isNotEmpty(accountTypeName)) {
				builder.append(accountTypeName);
			}
			if (StringUtils.isNotEmpty(chargeTypeName)) {
				builder.append(chargeTypeName);
			}
			builder.append(notifyUrl);
			if (StringUtils.isNotEmpty(merchantIP)) {
				builder.append(merchantIP);
			}
			if (StringUtils.isNotEmpty(provinceCode)) {
				builder.append(provinceCode);
			}
			String secretKey = SecretKeyUtil.getInstance().getKey(userNo, req);
			if (StringUtils.isNotEmpty(secretKey)) {
				builder.append(secretKey);
			} else {
				ResponseDataXmlFormat.returnFailMsg(
						ExCodeDes.UNKNOW_ERROR.getCode(),
						ExCodeDes.UNKNOW_ERROR.getDescription(), resp);
				return false;
			}
			String data = builder.toString();

			boolean checked = UtilMD5Encryption.checkMD5SignatureOfUTF8(data,
					sign);
			if (checked) {
				result = true;
			} else {
				log.info("交易时,数字签名验证失败!!!");

				ResponseDataXmlFormat.returnFailMsg(
						ExCodeDes.SIGN_FAIL.getCode(),
						ExCodeDes.SIGN_FAIL.getDescription(), resp);
				return false;
			}
		}

		boolean checkedTotal = DataDeal.checkTotalPrice(buyNum, unitPrice,
				totalPrice);
		if (checkedTotal) {
			result = true;
		} else {
			log.info("交易时,商品价格输入有误!!!");
			ResponseDataXmlFormat.returnFailMsg(
					ExCodeDes.PRICE_ERROR.getCode(),
					ExCodeDes.PRICE_ERROR.getDescription(), resp);
			result = false;
		}

		return result;
	}
}
